<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/7 0007
 * Time: 下午 2:40
 */
namespace common\components\Services;
use common\components\DataHelper;
use common\models\QrcodeLog\QrcodeLog;
use common\models\WxPublic\WxPublic;
use EasyWeChat\Factory;

class Wechat
{
    const QRSCENE_PREFIX = 'qrscene_';

    public $app;

    public function __construct($config = [])
    {
        $this->app = static::getApp($config);
    }

    public static function NewWechat($appId, $secret, $log = false)
    {
        $cfg = [
            "app_id" => $appId,
            "secret" => $secret,
            'response_type'=>'array',
        ];
        $dir = \Yii::$app->getRuntimePath();
        $dir = trim($dir, DIRECTORY_SEPARATOR);
        if ( $log ) {
            $cfg["log"] = [
                'level' => 'debug',
                'file' =>  is_string($log) ?  $dir.DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'wechat.'.$log.'.log' : $dir.DIRECTORY_SEPARATOR.'wechat.'.$appId.'.log',
            ];
        }
        $self = new self($cfg);
        return $self;
    }

    public static function getApp($config = [])
    {
        if ( !$config ) {
            $config = [];
        }

        return Factory::officialAccount($config);
    }

    /**
     * 创建临时二维码给代理商
     * @param int $type
     * @param null $agentId
     * @param array $extraData
     * @param string|null $ip
     * @param int $timeout
     * @return array
     */
    public function generateTemporaryQrCodeForAgent(int $type, $agentId = null, array $extraData = [], string $ip = null, int $timeout = QrcodeLog::VALID_DURATION)
    {
        return $this->createTemporaryQrCode(QrcodeLog::USER_TYPE_AGENT, $type, $agentId, $extraData, $ip, $timeout);
    }

    public function generateTemporaryQrCodeForMnanger(int $type, $userId = null, array $extraData = [], string $ip = null, int $timeout = QrcodeLog::VALID_DURATION)
    {
        return $this->createTemporaryQrCode(QrcodeLog::USER_TYPE_MANGER, $type, $userId, $extraData, $ip, $timeout);
    }

    public function generateTemporaryQrCodeForAdmin(int $type, $userId = null, array $extraData = [], string $ip = null, int $timeout = QrcodeLog::VALID_DURATION)
    {
        return $this->createTemporaryQrCode(QrcodeLog::USER_TYPE_ADMIN, $type, $userId, $extraData, $ip, $timeout);
    }

    public function generateTemporaryQrCodeForNil(int $type, array $extraData = [], string $ip = null, int $timeout = QrcodeLog::VALID_DURATION)
    {
        return $this->createTemporaryQrCode(QrcodeLog::USER_TYPE_NIL, $type, null, $extraData, $ip, $timeout);
    }
    /**
     * 创建临时二维码
     * @param int $userType
     * @param int $type
     * @param null $userId
     * @param array $extraData
     * @param string|null $ip
     * @param int $timeout
     * @return array
     */
    public function createTemporaryQrCode(int $userType, int $type, $userId = null, array $extraData = [], string $ip = null, int $timeout = QrcodeLog::VALID_DURATION)
    {
        $transaction = \Yii::$app->getDb()->beginTransaction();
        try {
            $qrLogRet = QrcodeLog::add($userType, $type, $userId, $extraData, $ip);
            if ( $qrLogRet ) {
                $qrRet = $this->app->qrcode->temporary($qrLogRet->id, $timeout);
                $qrLogRet->wechat_url = $qrRet["url"];
                $qrLogRet->update(0);
            } else {
                $transaction->rollBack();
                return [
                    'status' => false,
                    'message'    => '创建二维码失败，请稍候重试。',
                ];
            }
        } catch ( \Exception $e ) {
            $transaction->rollBack();
            return [
                'status' => false,
                'message'    => '创建二维码失败，请稍候重试。' . $e->getMessage(),
            ];
        }

        $transaction->commit();
        return [
            "status" => true,
            "message" => "操作成功",
            "data" => [
                "url" => $qrRet["url"],
                "imageUrl" => $this->app->qrcode->url($qrRet["ticket"]),
                "id" => $qrLogRet->id,
                "timeout" => time() + $timeout
            ]
        ];
    }

    public function eventHandler($message)
    {
        $result = '';
        // 事件类型
        switch ($message["Event"]) {
            // 关注
            case 'subscribe':
                // 手机微信扫码
                $sceneId = str_replace(self::QRSCENE_PREFIX, '', $message["EventKey"]);
                $result  = $this->qrcodeLogSceneIdHandler($message, $sceneId);
                break;
            // 取消关注
            case 'unsubscribe':
                // 手机微信扫码
                $this->unSubscribe($message["FromUserName"]);
                $result = '已取消关注';
                break;
            case 'LOCATION':
                break;
            case 'SCAN':
                // 手机微信扫码
                $sceneId = str_replace(self::QRSCENE_PREFIX, '', $message["EventKey"]);
                $result = $this->qrcodeLogSceneIdHandler($message, $sceneId);
                break;
        }
        return $result;
    }

    public function unSubscribe($openId)
    {
        return ;
    }

    public function qrcodeLogSceneIdHandler($message, $sceneId)
    {
        if ( DataHelper::isEmpty($sceneId) ) {
            return "";
        }

        $qrCodeLogRet = QrcodeLog::findOne($sceneId);
        $result    = '二维码已过期，请重新扫码';

        if ( !$qrCodeLogRet || $qrCodeLogRet->scan == QrcodeLog::SCAN_YES ) {
            return $result;
        }
        $ret = "【操作成功】";
        switch ( $qrCodeLogRet->type ) {
            case QrcodeLog::TYPE_WX_PUBLIC:
                $ret = $this->handleWxPublic($message, $qrCodeLogRet);
                break;
        }
        $qrCodeLogRet->markSuccess($message["FromUserName"], $message);

        return $ret;
    }

    public function handleWxPublic($message, QrcodeLog $qrCodeLog)
    {
        $openId = $message["FromUserName"];
        $id = $qrCodeLog->getExtendJson(QrcodeLog::EXTENDS_JSON_KEY_WX_PUBLIC_ID);
        $wxPublic = WxPublic::findOne($id);
        if ( !$wxPublic ) {
            return "无效的记录，请重新扫码 【".$qrCodeLog->id . "--" . $id."】";
        }
        //添加关注数量
        $wxPublic->addTotalFollow($openId);
        return $wxPublic->reply_msg . "\r\n\r\n" . "您的验证码为：【".$qrCodeLog->getExtendJson(QrcodeLog::EXTENDS_JSON_KEY_VERIFY_CODE)."】";
    }
}